#include <SPI.h>
#include <GD.h>

static PROGMEM prog_uchar piano[] = {

0x10,  0x20,  0x9c,  0x5e,  0x1e,  0x5a,  0x0d,  0x56,  0xf7,  0x30,  0xb1,  0x25,  0xb3,  0x38,  0x43,  0x24, 
0xc7,  0x68,  0xed,  0x1b,  0x29,  0x28,  0xfb,  0x33,  0xfb,  0x13,  0xf0,  0x17,  0xf5,  0x07,  0x5b,  0x10, 
0xee,  0x0b,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 
0x00,  0x00,  0x02,  0x03,  0x03,  0x05,  0x00,  0x00,  0x00,  0x00,  0x04,  0x0e,  0x08,  0x10,  0x12,  0x17, 
0x21,  0x00,  0x02,  0x04,  0x05,  0x05,  0x00,  0x07,  0x08,  0x09,  0x08,  0x11,  0x0d,  0x15,  0x15,  0x28, 
0x27,  0x2b,  0x03,  0x04,  0x05,  0x05,  0x00,  0x07,  0x07,  0x08,  0x0c,  0x11,  0x12,  0x14,  0x17,  0x27, 
0x24,  0x2b,  0x03,  0x04,  0x05,  0x06,  0x00,  0x06,  0x08,  0x06,  0x0b,  0x10,  0x0f,  0x14,  0x19,  0x25, 
0x21,  0x29,  0x03,  0x02,  0x05,  0x05,  0x00,  0x05,  0x07,  0x05,  0x0a,  0x0e,  0x06,  0x15,  0x18,  0x1e, 
0x1c,  0x1f,  0x02,  0x01,  0x04,  0x04,  0x00,  0x04,  0x05,  0x04,  0x09,  0x0a,  0x04,  0x13,  0x15,  0x16, 
0x15,  0x16,  0x01,  0x00,  0x03,  0x03,  0x00,  0x02,  0x04,  0x03,  0x08,  0x07,  0x05,  0x0f,  0x10,  0x10, 
0x10,  0x0d,  0x01,  0x00,  0x02,  0x02,  0x00,  0x01,  0x02,  0x02,  0x05,  0x04,  0x05,  0x0b,  0x0b,  0x10, 
0x09,  0x09,  0x00,  0x00,  0x02,  0x01,  0x00,  0x01,  0x01,  0x01,  0x04,  0x02,  0x01,  0x07,  0x05,  0x11, 
0x04,  0x06,  0x00,  0x00,  0x01,  0x00,  0x00,  0x01,  0x00,  0x01,  0x03,  0x01,  0x00,  0x05,  0x02,  0x0f, 
0x02,  0x06,  0x00,  0x00,  0x01,  0x00,  0x00,  0x01,  0x00,  0x01,  0x02,  0x02,  0x00,  0x03,  0x01,  0x0d, 
0x02,  0x08,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x00,  0x02,  0x01,  0x03,  0x02,  0x0a, 
0x02,  0x0a,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x01,  0x00,  0x00,  0x02,  0x01,  0x04,  0x04,  0x05, 

0x02,  0x0c,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x02,  0x00,  0x05,  0x04,  0x01, 
0x01,  0x0b,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x01,  0x01,  0x00,  0x05,  0x04,  0x01, 
0x01,  0x07,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x02,  0x01,  0x00,  0x05,  0x04,  0x01, 
0x01,  0x06,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x01,  0x00,  0x03,  0x01,  0x00,  0x05,  0x04,  0x02, 
0x01,  0x05,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x03,  0x00,  0x00,  0x04,  0x04,  0x02, 
0x01,  0x04,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x03,  0x00,  0x00,  0x03,  0x04,  0x02, 
0x01,  0x04,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x03,  0x00,  0x00,  0x02,  0x03,  0x03, 
0x01,  0x03,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x02,  0x00,  0x00,  0x01,  0x03,  0x03, 
0x00,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x02,  0x00,  0x01,  0x00,  0x03,  0x02, 
0x00,  0x02,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x02,  0x00,  0x02,  0x00,  0x02,  0x02, 
0x00,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,  0x01,  0x00,  0x02,  0x02, 
0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x00,  0x02,  0x02, 
0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x01, 
0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x01, 
0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00, 
0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00, 

0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x01,  0x00, 
0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 
0x01,  0x00, 
};

void setup()
{
  int i;

  GD.begin();
  GD.ascii();
  GD.putstr(0, 0,"Instruments");

  PROGMEM prog_uchar *instr = piano;
  byte voices = pgm_read_byte(instr++);
  byte duration = pgm_read_byte(instr++);
  for (byte i = 0; i < voices; i++) {
    GD.voice(i, 0, (pgm_read_word(instr) * 184L) >> 10, 0, 0);
    instr += 2;
  }
  for (;;) {
    prog_uchar *amps = instr;
    for (byte i = 0; i < duration; i++) {
      for (byte j = 0; j < voices; j++) {
        byte v = pgm_read_word(amps++);
        GD.wr(VOICES + 4 * j + 2, v);
        GD.wr(VOICES + 4 * j + 3, v);
      }
      GD.waitvblank();
      GD.waitvblank();
    }
  }
}

void loop()
{
}

